home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <regexp.h>
- #include <limits.h>
- #include <dirent.h>
- #include "extras.h"
-
- /*
- char *wildcard(char *pathname)
- Return matches for a wildcard filename. If <pathname> is not
- NULL, the first file which matches <pathname> will be returned.
- The <pathname> may contain wildcards only in the filename portion,
- not in any sub-directories. Subsequent calls to wildcard() with
- a NULL argument return the next matching filename. NULL is
- returned when no more files match. Note: the pointer returned
- points to an internal buffer which is overwritten with each
- call. It should not be modified, and should be copied into a
- safe place if you want to save the value.
- */
-
- static DIR *handle = NULL;
- static regexp *match = NULL;
-
- static void release_handle()
- {
- if (handle)
- closedir(handle);
- if (match)
- free(match);
- }
-
- char *wildcard(pathname)
- const char *pathname;
- {
- static int first_time = 1;
- static char pathbuf[PATH_MAX];
- static char pattern[2 * NAME_MAX];
- static char *s;
- register char *t, *u;
- struct dirent *D;
-
- /* Clean up behind ourselves */
- if (first_time) {
- first_time = 0;
- atexit(release_handle);
- }
-
- if (pathname) {
- /* Shut down the previous wildcard search, if any, and set up for a
- new one. */
- if (handle) {
- closedir(handle);
- handle = NULL;
- }
- if (match) {
- free(match);
- match = NULL;
- }
- t = strrpbrk(pathname, "/\\");
- if (!t) {
- strcpy(pathbuf, "./");
- s = pathbuf + 2;
- t = pathname;
- } else {
- t++;
- strncpy(pathbuf, pathname, (int)(t - pathname));
- s = pathbuf + (t - pathname);
- }
-
- handle = opendir(pathbuf);
- if (!handle)
- return NULL;
-
- /* Translate the filename component from a DOS-style wildcard
- expression to a regular expression for regexp(). */
- u = pattern;
- *u++ = '^';
- for (; *t; t++) {
- switch (*t) {
- case '*':
- *u++ = '.';
- *u++ = '*';
- break;
- case '?':
- *u++ = '.';
- break;
- case '.':
- *u++ = '\\';
- *u++ = '.';
- break;
- default:
- *u++ = *t;
- }
- }
- *u++ = '$';
- *u = '\0';
- match = regcomp(pattern);
- if (!match) {
- closedir(handle);
- handle = NULL;
- return NULL;
- }
- }
-
- /* Now try to read a filename from the directory, and match it with
- the regular expression. */
- for (;;) {
- D = readdir(handle);
- if (!D) { /* end of directory */
- closedir(handle);
- handle = NULL;
- free(match);
- match = NULL;
- return NULL;
- }
- if (regexec(match, D->d_name, 1) == 0)
- continue;
- strcpy(s, D->d_name);
- return pathbuf;
- }
- }
-